/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package src.view.customer;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;
import org.primefaces.context.RequestContext;
import org.primefaces.event.CloseEvent;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.UploadedFile;
import src.domain.customer.Corbod;
import src.domain.customer.Corbuslic;
import src.domain.customer.Cuscor;
import src.domain.customer.Customer;
import src.domain.security.Users;
import src.services.customer.*;
import src.util.Constanta;
import src.util.Messager;
import src.util.Utils;
import src.view.security.LoginBean;

/**
 *
 * @author Yusup Jauhari Shandi <in.visi>
 */

@ManagedBean
@SessionScoped
public class CuscorBean  implements java.io.Serializable{
    private List<Cuscor> cuscors;
    private List<SelectItem> availableNationality,availableBusentype,availableCorebus,availableBuslic;
    private List<SelectItem> availableProvince,availableDistrict, availableResprovince, availableResdistrict;
    private Cuscor selectedData, insertedData;
    private Corbod unsaveboard;
    private Corbuslic unsaveBuslic;
    private UploadedFile uploadedFile;
    
    private boolean editMode=true, editDetailMode=true;
    private CuscorModel helper;
    private Integer buslicIdx, nationalityIdx, buslicId, nationalityId;
    private static final int BUFFER_SIZE = 6124; 
    private Users user;
    
    public CuscorBean() {
        ambilUser();
        this.helper = new CuscorModel(); 
        this.cuscors = this.helper.findAll(null);
        this.insertedData = null;
        this.selectedData = null;
        for (int i=0; i < this.cuscors.size();i++ ){
            CustomerModel x = new CustomerModel();
            this.cuscors.get(i).setCustomer(x.getById(this.cuscors.get(i).getCustomerId()));
        }
    }
    
    private void ambilUser() {
        FacesContext context = FacesContext.getCurrentInstance();
        LoginBean logBean = (LoginBean) context.getApplication().evaluateExpressionGet(context, "#{loginBean}", LoginBean.class);
        this.user = logBean.getSelectedUser();
    }
       
    private boolean cekConfig() {
        return (user.getBranch().getBranchId()!=null ? true:false);
    }
    
    public Cuscor getInsertedData() {
        return insertedData;
    }

    public void setInsertedData(Cuscor insertedData) {
        this.insertedData = insertedData;
    }

    public Cuscor getSelectedData() {
        return selectedData;
    }

    public void setSelectedData(Cuscor selectedData) {
        this.selectedData = selectedData;
    }

    public UploadedFile getUploadedFile() {
        return uploadedFile;
    }

    public void setUploadedFile(UploadedFile uploadedFile) {
        this.uploadedFile = uploadedFile;
    }
    
    
    private void initForm(){
         BusentypeModel bus = new BusentypeModel();
         availableBusentype = bus.listAll();
         CorebusModel cr = new CorebusModel();
         availableCorebus = cr.listAll();         
         NationalityModel nat = new NationalityModel();
         availableNationality = nat.listAll();
         BuslicModel buslc = new BuslicModel();
         availableBuslic = buslc.listAll();
    }
    
     public void loadCuscors () {
        Map<String, String> custfilter = new HashMap<>();
      //  savfilter.put("approvalUid", null);
     //   custfilter.put("closeDate", null);
     //   custfilter.put("closedBy", null);
     //   custfilter.put("order", "accountNo");
            custfilter.put("order", "customer.cif");      
        this.cuscors = helper.findAll(custfilter);
    }
     
    public List<Cuscor> getCuscors() {
        return cuscors;
    }
    
    public void handleClose(CloseEvent event) {
        this.selectedData = null;
        this.insertedData = null;
        this.editMode = true; 
    }
    
    public void handleCountryChange(Integer country) {  
        if(country !=null ) {
            Map<String, String> filters = new HashMap<>();       
            filters.put("tb.countryId", String.valueOf(country.intValue()));
            ProvinceModel prov = new ProvinceModel();
            this.availableProvince = prov.listAll(filters);  
        } 
    }  
     
     public void handleProvinceChange(Integer province) {  
        if(province !=null ) {
            Map<String, String> filters = new HashMap<>();       
            filters.put("tb.provinceId", String.valueOf(province.intValue()));
            DistrictModel district = new DistrictModel();
            this.availableDistrict = district.listAll(filters);  
        } 
    }  
          
    public void handleRescountryChange(Integer country) {  
        if(country !=null ) {
            Map<String, String> filters = new HashMap<>();       
            filters.put("tb.countryId", String.valueOf(country.intValue()));
            ProvinceModel prov = new ProvinceModel();
            this.availableResprovince = prov.listAll(filters);  
        } 
    }
    
    public void handleCIFChange() {  
        if(insertedData.getCustomer().getCif() !=null && !insertedData.getCustomer().getCif().equals(Constanta.AUTO_NUMBERING)) {
            boolean eksis = new CustomerModel().isCIFExist(insertedData.getCustomer().getCif(), insertedData.getCustomer().getCustomerId());
            if (eksis) {
                Messager.showWarning("cifIsExist");
                insertedData.getCustomer().setCif(Constanta.AUTO_NUMBERING);
            }
        } 
    }  
     
     public void handleResprovinceChange(Integer province) {  
        if(province !=null ) {
            Map<String, String> filters = new HashMap<>();       
            filters.put("tb.provinceId", String.valueOf(province.intValue()));
            DistrictModel district = new DistrictModel();
            this.availableResdistrict = district.listAll(filters);  
        } 
    }  
     
    private void removeEmptyBoard(){
        for(int i = 0; i<insertedData.getCustomer().getCorbods().size(); i++){
            if(insertedData.getCustomer().getCorbods().get(i).getNationalityId() == null ) {
                insertedData.getCustomer().getCorbods().remove(i);
                i--;
            }
        }
    }
    
    private void removeEmptyBuslic(){
        for(int i = 0; i<insertedData.getCustomer().getCorbuslics().size(); i++){
            if(insertedData.getCustomer().getCorbuslics().get(i).getBuslicId() == null ) {
                insertedData.getCustomer().getCorbuslics().remove(i);
                i--;
            }
        }
    }
    
    public void handleRemoveBoard() {  
        if (insertedData.getCustomer().getCorbods().size() == 1) 
            this.insertedData.getCustomer().getCorbods().add(new Corbod());
    }
    
    public void handleRemoveBuslic() {  
        if (insertedData.getCustomer().getCorbuslics().size() == 1) 
            this.insertedData.getCustomer().getCorbuslics().add(new Corbuslic());
    }
    
    public void newBoard() {
        this.unsaveboard = new Corbod();
        editDetailMode = false;
    }
    
    public void newBuslic() {
        this.unsaveBuslic = new Corbuslic();
        editDetailMode = false;
    }
    
    public void newData() {  
       initForm();
        this.selectedData = null;
        this.editMode = false;
        this.insertedData = new Cuscor();
        this.insertedData.getCustomer().getCorbods().add(new Corbod());
        this.insertedData.getCustomer().getCorbuslics().add(new Corbuslic());
        
    }
    
    public void editBoard(Corbod data) {
        this.nationalityId = data.getNationalityId();
        this.nationalityIdx = insertedData.getCustomer().getCorbods().indexOf(data);
        this.unsaveboard = Corbod.clone(data);
        editDetailMode = true;
    }

    public void editBuslic(Corbuslic data) {
        this.buslicId = data.getBuslicId();
        this.buslicIdx = insertedData.getCustomer().getCorbuslics().indexOf(data);
        this.unsaveBuslic = Corbuslic.clone(data);
        editDetailMode = true;
    }
    
    public void saveBoard() {
        boolean success=true;
        try {
            this.unsaveboard.setNationalityId(nationalityId);
            
            if(!editDetailMode) {
                this.insertedData.getCustomer().getCorbods().add(unsaveboard);
                removeEmptyBoard();
            } else selectedData.getCustomer().getCorbods().set(nationalityIdx, Corbod.clone(unsaveboard));

        } catch (RuntimeException e) {success=false;
        } finally {Messager.showSaveUpdateStatus(success);}
    }
    
    public void saveBuslic() {
        boolean success=true;
        try {
            this.unsaveBuslic.setBuslicId(buslicId);
            
            if(!editDetailMode) {
                this.insertedData.getCustomer().getCorbuslics().add(unsaveBuslic);
                removeEmptyBuslic();
           } else selectedData.getCustomer().getCorbuslics().set(buslicIdx, Corbuslic.clone(unsaveBuslic));
            
        } catch (RuntimeException e) {success=false;
        } finally {Messager.showSaveUpdateStatus(success);}
    }
    
    public void openData() {
        initForm();

        this.editMode = true;
        this.insertedData = Cuscor.clone(selectedData);
        
        if (insertedData.getCustomer().getCorbods().isEmpty()) 
            this.insertedData.getCustomer().getCorbods().add(new Corbod());
        
        if (insertedData.getCustomer().getCorbuslics().isEmpty()) 
            this.insertedData.getCustomer().getCorbuslics().add(new Corbuslic());
        
        handleCountryChange(insertedData.getCustomer().getIdCountryId());
        handleProvinceChange(insertedData.getCustomer().getIdProvinceId());
        handleRescountryChange(insertedData.getCustomer().getResCountryId());
        handleResprovinceChange(insertedData.getCustomer().getResProvinceId());
    }
     
    private void save() {
        
        RequestContext context = RequestContext.getCurrentInstance();
                
        Customer customer = insertedData.getCustomer();
        
        customer.setLogUpdated(Utils.logActions(user.getUserName(), new java.util.Date()));
        if (!editMode) customer.setLogCreated(Utils.logActions(user.getUserName(), new java.util.Date()));
        
        //List<Corbod> corbods = customer.getCorbods();
        //List<Corbuslic> corbuslics = customer.getCorbuslics();
        
        //customer.setCorbods(corbods);
        //customer.setCorbuslics(corbuslics);
                
     //   if (uploadedFile!=null){
      ////      customer.setSpecimen(uploadedFile.getFileName());
     //   }
        
        customer.setCustomerType(Constanta.CUSTOMER_CORPORATE);
        customer.setCuscor(insertedData);
        if (customer.getIdcardId()==-1) customer.setIdcardId(null);
        if (insertedData.getBusentypeId()==-1) insertedData.setBusentypeId(null);
        insertedData.setCustomer(customer);
       
        boolean success = helper.saveData(customer);
        if (success==true) {
            if (this.editMode==false) this.cuscors.add(insertedData);
            else {
                int i = cuscors.indexOf(selectedData);
                if (i <= cuscors.size()) cuscors.set(i, Cuscor.clone(insertedData));
            }
            editMode = true;
            
        } else {
            if (this.editMode==false) { 
                insertedData.setCustomerId(null);
                insertedData.getCustomer().setCustomerId(null);
            }
        }
        
        Messager.showSaveUpdateStatus(success);
        context.addCallbackParam("success", success);
    }
    
    public void trySave() {
        boolean configured = cekConfig();
        if(configured==true) {
            newNumber();
            save();
            
        } else Messager.showWarning("unconfig");
    }
    
    public void delete() {
        
        RequestContext context = RequestContext.getCurrentInstance();  
        Customer customer = selectedData.getCustomer();
        customer.setCuscor(selectedData);
        selectedData.setCustomer(customer);
                
        boolean success = helper.deleteData(customer);
        
        if (success) {
            this.cuscors.remove(selectedData);
            this.selectedData = null;
        } 
        
        Messager.showDeleteStatusConstaint(success);  
        context.addCallbackParam("success", success);  
    }
 
    public String selectItemValueOf(List<SelectItem> avblList, Integer id) {
        return (String) Utils.selectItemValueOf(avblList, id);
    }
        
    private void newNumber() {
        //String cif = insertedData.getCustomer().getCif();
        //if (cif.equals(Constanta.AUTO_NUMBERING)) {
        //    cif =  new CRUEDService().getNextTrxNumber(10, user.getBranch().getBranchId(), 0, 1).getTrxNum();
        //    insertedData.getCustomer().setCif(cif);
        //}
    }
    
    public boolean isEditMode() {
        return editMode;
    }

    public List<SelectItem> getAvailableBusentype() {
        return availableBusentype;
    }

    public List<SelectItem> getAvailableBuslic() {
        return availableBuslic;
    }

    public List<SelectItem> getAvailableCorebus() {
        return availableCorebus;
    }

    public List<SelectItem> getAvailableNationality() {
        return availableNationality;
    }

    public Integer getBuslicId() {
        return buslicId;
    }

    public Corbuslic getUnsaveBuslic() {
        return unsaveBuslic;
    }

    public Corbod getUnsaveboard() {
        return unsaveboard;
    }

    public void setBuslicId(Integer buslicId) {
        this.buslicId = buslicId;
    }

    public Integer getNationalityId() {
        return nationalityId;
    }

    public void setNationalityId(Integer nationalityId) {
        this.nationalityId = nationalityId;
    }
    
    public void setUnsaveBuslic(Corbuslic unsaveBuslic) {
        this.unsaveBuslic = unsaveBuslic;
    }

    public void setUnsaveboard(Corbod unsaveboard) {
        this.unsaveboard = unsaveboard;
    }

    public List<SelectItem> getAvailableDistrict() {
        return availableDistrict;
    }

    public List<SelectItem> getAvailableProvince() {
        return availableProvince;
    }

    public List<SelectItem> getAvailableResdistrict() {
        return availableResdistrict;
    }

    public List<SelectItem> getAvailableResprovince() {
        return availableResprovince;
    }
    

    public void handleFileUpload(FileUploadEvent event) {
       
    ExternalContext extContext=FacesContext.getCurrentInstance().getExternalContext();
            
    File result = new File(extContext.getRealPath("//upload//corporate//" + 
          event.getFile().getFileName()));
    //System.out.println(extContext.getRealPath("//WEB-INF//files//" + 
    //      event.getFile().getFileName()));

    try {
            InputStream inputStream;
            try (FileOutputStream fileOutputStream = new FileOutputStream(result)) {
                byte[] buffer = new byte[BUFFER_SIZE];
                int bulk;
                inputStream = event.getFile().getInputstream();
                while (true) {
                       bulk = inputStream.read(buffer);
                       if (bulk < 0) {
                           break;
                        }
                       fileOutputStream.write(buffer, 0, bulk);
                       fileOutputStream.flush();
                 }
            }
        inputStream.close();
        this.insertedData.getCustomer().setSpecimen(event.getFile().getFileName());
       FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName()
                                                                  + " is uploaded.");
        FacesContext.getCurrentInstance().addMessage(null, msg);

        } catch (IOException e) {

            FacesMessage error = new FacesMessage(FacesMessage.SEVERITY_ERROR, 
                                                 "The files were not uploaded!", "");
            FacesContext.getCurrentInstance().addMessage(null, error);
            
     }       
   } 
}
